package com.igoal.web;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.igoal.common.SessionConstants;
import com.igoal.dto.GoalDTO;
import com.igoal.dto.UserDTO;
import com.igoal.service.ActionLoggerService;
import com.igoal.service.CommonService;
import com.igoal.service.GoalEntryManager;
import com.igoal.service.GoalManager;
import com.igoal.service.MessageManager;
import com.igoal.service.UserAccountService;
import com.igoal.service.UserManagerExt;
import com.igoal.utils.ConvertUtils;
import com.igoal.utils.WebUtils;
import com.igoal.web.model.BaseModel;
import com.igoal.web.model.SettingsModel;

public abstract class BaseFormController extends SimpleFormController implements ViewController{
	protected GoalManager goalManager;
	protected UserManagerExt userManagerExt;
	protected CommonService commonService;
	protected MessageManager messageManager;
	protected ActionLoggerService actionLoggerService;
	protected GoalEntryManager goalEntryManager;
	protected UserAccountService userAccountService;
	
	@Qualifier("controllerDelegate")
	private BaseControllerDelegate delegate;
	
	@Autowired
	public void setUserAccountService(UserAccountService userAccountService) {
		this.userAccountService = userAccountService;
	}

	@Autowired
	public void setDelegate(BaseControllerDelegate delegate) {
		this.delegate = delegate;
	}
	
	@Autowired
	public void setActionLoggerService(ActionLoggerService actionLoggerService) {
		this.actionLoggerService = actionLoggerService;
	}

	@Deprecated
	public boolean isLoginUser(HttpServletRequest request) {
		Object oUser = request.getSession(true).getAttribute(SessionConstants.USER_SESSION);
		return oUser != null;
	}

	@Deprecated
	public UserDTO getUserSession(HttpServletRequest request) {
		Object oUser = request.getSession(true).getAttribute(SessionConstants.USER_SESSION);
		if (oUser != null)
			return (UserDTO) oUser;
		return null;
	}

	public boolean isLoginUser() {
		return delegate.isLoginUser();
	}

	public String getUserInSession() {
		return delegate.getUserInSession();
	}

	public UserDTO getUserSession() {
		return delegate.getUserSession(userManagerExt);
	}

	public long getGoalId(HttpServletRequest request) {
		Object goalId = request.getAttribute("goalId");
		if (goalId != null) {
			return ConvertUtils.toLong(goalId.toString(), -1);
		}

		return -1;
	}

	/**
	 * The notification information creator
	 * 
	 * @param user
	 *            user in session
	 * @param model
	 *            the controller model that extends from {@link BaseModel}
	 */
	public void initUserNotification(UserDTO user, BaseModel model) {
		delegate.initUserNotification(userManagerExt, messageManager, actionLoggerService, user,
				model);
	}
	
	public void initUserStatus(UserDTO user, BaseModel model){
		delegate.initUserStatus(userManagerExt, user, model);
	}
	
	public void initUserAvatar(UserDTO user, BaseModel model){
		delegate.initUserAvatar(userManagerExt, user, model);
	}
	
	public void initUserActivities(UserDTO user, BaseModel model){
		delegate.initUserActivities(actionLoggerService, user, model);
	}
	
	/**
	 * The user profile notification creator
	 * 
	 * @param user
	 *            user in session
	 * @param model
	 *            the controller model that extends from {@link BaseModel}
	 */
	public void initUserProfileNotification(UserDTO user, BaseModel model) {
		delegate.initUserProfileNotification(userManagerExt, user, model);
	}

	public void initPeopleYouMayKnow(UserDTO user, BaseModel model) {
		delegate.initPeopleYouMayKnow(userManagerExt, user, model);
	}
	
	public void initMustDoGoal(BaseModel model){
		delegate.initMustDoGoal(model, goalManager);
	}

	/**
	 * The friend list creator
	 * 
	 * @param user
	 *            user in session
	 * @param model
	 *            the controller model that extends from {@link BaseModel}
	 */
	public void initFriendList(UserDTO user, BaseModel model) {
		delegate.countFriends(userManagerExt, user, model);
		delegate.initRandomFriendList(userManagerExt, user, model);
	}

	/**
	 * Call the built-in creator
	 * 
	 * @param user
	 *            user in session
	 * @param model
	 *            the controller model that extends from {@link BaseModel}
	 */
	@Deprecated
	public void simpleModelInitialize(UserDTO user, BaseModel model) {
		initTopZone(user, model);
		initRightZone(user, model);
		initSessionInformation(model);
	}

	public void initRightZone(UserDTO user, BaseModel model) {
		initFriendList(user, model);
		initUserProfileNotification(user, model);
		initUserActivities(user, model);
		if(goalManager != null){
			List<GoalDTO> topGoals = goalManager.getTopGoals(user);
			model.setTopGoals(WebUtils.buildGoalCloud(topGoals));
	
			List<GoalDTO> commonGoals = goalManager.getCommonGoals(user);
			model.setCommonGoals(WebUtils.buildGoalCloud(commonGoals));
		}
	}

	public void initTopZone(UserDTO user, BaseModel model) {
		initUserStatus(user, model);
		initUserNotification(user, model);
		initUserAvatar(user, model);
		initSessionInformation(model);
		initMustDoGoal(model);
	}

	public void initSessionInformation(BaseModel model) {
		delegate.initSessionInformation(model, userManagerExt);
		if(isLoginUser()){
			String username = getUserInSession();
			SettingsModel settingsModel = model.getSettings();
			if(settingsModel == null){
				settingsModel = new SettingsModel();
			}
			settingsModel.setAccountActivated(userAccountService.isActivatedAccount(username));
		}
	}

	public void applyModel(ModelMap modelMap, BaseModel model) {
		delegate.applyModel(modelMap, model);
	}
	
	public abstract String getViewPrefix();
}
